
from rest_framework import serializers
from django_redis  import get_redis_connection

from redis import RedisError
import logging



class SMSCodeSerializer(serializers.Serializer):
    # 指定要校验的字段,字段名必须与外界传入的query_params一致
    image_code_id=serializers.UUIDField()
    text=serializers.CharField(max_length=4,min_length=4)
    # 定义一个函数 使其校验 因为要两个属性进行对比 所以使用validate方法
    def validate(self, attrs):
        image_code_id=attrs["image_code_id"]
        text=attrs["text"]
    #     与数据库进行连接  查询真正的图片验证码
        redis_conn=get_redis_connection("verify_codes")
    #     获取缓存在redis中的数据
        real_image_code_text=redis_conn.get("img_%s"%image_code_id)
    #     判断没有获取到图片验证码的时候
        if  real_image_code_text is None:
            raise serializers.ValidationError("图片验证码无效")
    #         为了实现图片验证码的一次性,当获取到图片验证码将其从redis数据库中删除
    #         因为有可能会删除失败 为了防止删除失败还继续执行代码  所以try一下
        try:
            redis_conn.delete("img_%s"%image_code_id)
        except RedisError as e:
            logging.error(e)
    #     因为在py3中获取到的redis数据是byte类型 所以需要解码
        real_image_code_text=real_image_code_text.decode()
    #     使用户输入的图片验证码内容与获取到的数据进行对比
        if text.lower() != real_image_code_text.lower():
            raise serializers.ValidationError("图片验证码有误")
#         判断短信验证码是否在60s内  context上下文   kwargs参数
        mobile=self.context["view"].kwargs["mobile"]
#         根据手机号获取短信验证码
        send_flag=redis_conn.get("send_flag_%s"%mobile)
        if send_flag:
            raise serializers.ValidationError("请求次数过于频繁")
        return attrs

